<!--
 * @Author: 黄达全
 * @Date: 2024-08-28 17:10:11
 * @LastEditTime: 2024-08-29 17:59:06
-->
<script lang="ts" setup>
import CategoryApi from "@/api/model/category"
import { CategoryTreeVO, CategoryAddForm } from "@/common/type"
import { ref, watch } from "vue"
import { useTable } from "@/hooks/useTable"
import drawer from "@/components/drawer.vue"
import type Node from 'element-plus/es/components/tree/src/model/node'
import type {
    AllowDropType
} from 'element-plus/es/components/tree/src/tree.type'
import { ElTree, FormInstance } from 'element-plus'

import selectIcon from "@/components/selectIcon.vue"


interface Tree {
    [key: string]: any
}



const treeData = ref<CategoryTreeVO[]>([])
const defaultExpandedKeys = ref<number[]>([])
const emits = defineEmits(["update:modelValue"])

const getTreeData = async () => {
    const { data } = await CategoryApi.tree()
    treeData.value = data
    emits("update:modelValue", treeData.value[0].id)
}

getTreeData()

const defaultProps = {
    children: "",
    label: "name"
}

const handleNodeClick = (e: CategoryTreeVO) => {
    emits("update:modelValue", e.id)
}

const handleCommand = (e: string) => {
    switch (e) {
        case "refresh":
            getTreeData()
            break;
        case "add":
            openAddGoodsCategoryDrawer()
            break;
    }
}

const {
    isAddMode,
    submitHandle,
    initForm,
    formRules,
    del,
    drawerRef,
    editId,
    update
} = useTable<CategoryTreeVO, CategoryAddForm>({
    initForm: {
        name: '',
        status: 1,
        order: 1,
        parentId: 0,
        icon:""
    },
    // @ts-ignore
    formRules: {  //ts报错，无法有效解决
        name: [
            { required: true, message: '请输入分类名称', trigger: 'blur' },
            { min: 2, max: 20, message: '长度在 2 到 20 个字符', trigger: 'blur' }
        ],
        status: [
            { required: true, message: '请选择状态', trigger: 'change' }
        ],
        icon: [
            { required: true, message: '请选择图标', trigger: 'change' }
        ]
    },
    addItem: (form) => CategoryApi.add(form),
    deleteItem: (ids) => CategoryApi.delete(ids),
    updateItem: (form) => CategoryApi.update(form),
    title: "商品分类"
})

// 表单引用
const formRef = ref<FormInstance>()

const openAddGoodsCategoryDrawer = () => {
    isAddMode.value = true
    initForm.parentId = 0
    initForm.name = ''
    initForm.icon = ''
    initForm.order = 1
    initForm.status = 1
    drawerRef.value.open()
    // 延迟清除校验结果
    setTimeout(() => {
        formRef.value?.clearValidate()
    }, 0)
}

const openEditGoodsCategoryDrawer = (row: CategoryTreeVO) => {
    isAddMode.value = false
    editId.value = row.id
    initForm.parentId = row.parentId
    initForm.name = row.name
    initForm.order = row.order
    initForm.icon = row.icon
    initForm.status = row.status
    drawerRef.value.open()
    // 延迟清除校验结果
    setTimeout(() => {
        formRef.value?.clearValidate()
    }, 0)
}

const submit = () => {
    submitHandle(() => {
        getTreeData()
        drawerRef.value.close()
    })
}

const handleChange = (e: number[]) => {
    initForm.parentId = e.reverse()[0]
}

const delTree = (id: number) => {
    del(id, getTreeData)
}

const allowDrop = (_draggingNode: Node, dropNode: Node, _type: AllowDropType) => {
    return dropNode.data.parentId === 0
}
const allowDrag = (draggingNode: Node) => {
    return draggingNode.data.parentId !== 0
}


const handleDragStart = (node: Node) => {
    editId.value = node.data.id
    initForm.name = node.data.name
    initForm.order = node.data.order
    initForm.status = node.data.status
}
const handleDrop = async (
    _draggingNode: Node,
    dropNode: Node,
) => {
    initForm.parentId = dropNode.data.id
    await update(getTreeData)
    defaultExpandedKeys.value = [editId.value as number]
}


const filterNode = (value: string, data: Tree) => {
    if (!value) return true
    return data.name.includes(value)
}

const treeRef = ref<InstanceType<typeof ElTree>>()
const searchMsg = ref<string>("")

watch(searchMsg, (val) => {
    treeRef.value!.filter(val)
})

</script>

<template>
    <div class="leftTree">

        <div class="filterForm">
            <div style="margin-right: 6px;font-size: 14px;">
                分类
            </div>
            <el-input style="width: 135px;margin-right: 6px;" size="small" v-model="searchMsg"></el-input>
            <el-dropdown @command="handleCommand">
                <el-icon size="17" style="cursor: pointer;"><el-icon-setting /></el-icon>
                <template #dropdown>
                    <el-dropdown-menu>
                        <el-dropdown-item command="refresh">刷新数据</el-dropdown-item>
                        <el-dropdown-item command="add">新增父分类</el-dropdown-item>
                    </el-dropdown-menu>
                </template>
            </el-dropdown>

        </div>
        <div class="tree">
            <el-tree ref="treeRef" :data="treeData" :props="defaultProps" @node-click="handleNodeClick" empty-text="暂无数据"
                :default-expanded-keys="defaultExpandedKeys" node-key="id" accordion draggable :allow-drop="allowDrop"
                :allow-drag="allowDrag" @node-drag-start="handleDragStart" @node-drop="handleDrop"
                :filter-node-method="filterNode">
                <template #default="{ data }">
                    <div class="tree-item">
                        <div class="title">
                            <el-tag 
                                size="small" 
                                :type="data.status === 1 ? 'success' : 'danger'"
                                style="margin-left: 5px;"
                            >
                                {{ data.status === 1 ? '开启' : '关闭' }}
                            </el-tag>
                            <el-icon v-if="data.icon" style="margin-right: 3px;">
                                <component :is="`el-icon-${data.icon}`" />
                            </el-icon>
                            {{ data.name }}
                            
                        </div>
                        <div class="icon_box">
                            <el-icon size="14" class="icon"
                                @click.stop="openEditGoodsCategoryDrawer(data)"><el-icon-edit /></el-icon>
                            <el-icon size="14" class="icon" @click.stop="delTree(data.id)"><el-icon-close /></el-icon>
                        </div>
                    </div>
                </template>
            </el-tree>

        </div>
        <drawer ref="drawerRef" :title="isAddMode ? '新增商品分类' : '修改商品分类'" direction="rtl" size="35%" @submit="submit">
            <template #rtl>
                <el-form 
                    :model="initForm" 
                    :rules="formRules" 
                    :label-width="130" 
                    validate-on-rule-change="false"
                    ref="formRef"
                >
                    <el-form-item label="父规格（可选）" prop="name">
                        <el-cascader v-model="initForm.parentId" @change="handleChange" :options="treeData" :props="{
                            checkStrictly: true,
                            value: 'id',
                            label: 'name',
                            children: 'children'
                        }" clearable placeholder="请选择父分类（可选）" />
                    </el-form-item>
                    <el-form-item label="分类名称" prop="name">
                        <el-input v-model="initForm.name" placeholder="请输入商品分类名称"></el-input>
                    </el-form-item>
                    <el-form-item label="图标" prop="icon">
                        <select-icon v-model="initForm.icon" />
                    </el-form-item>
                    <el-form-item label="状态" prop="status">
                        <el-switch v-model="initForm.status" :active-value="1" :inactive-value="0"
                            style="--el-switch-on-color: var(--primary-theme-color); --el-switch-off-color: #ccc" />
                    </el-form-item>
                    <el-form-item label="排序">
                        <el-input-number v-model="initForm.order"></el-input-number>
                    </el-form-item>
                </el-form>
            </template>
        </drawer>
    </div>
</template>

<style lang="scss" scoped>
.leftTree {
    width: 215px;
    height: 100%;
}

.tree {
    width: 215px;
    overflow-y: scroll;
    height: calc(100% - 40px);
    padding: 0px 10px 0px 10px;

    &::-webkit-scrollbar {
        width: 0;
    }

    .tree-item {
        display: flex;
        width: 100%;
        justify-content: space-between;
        align-items: center;
        padding-right: 5px;

        .title {
            flex: 1;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
            display: flex;
            align-items: center;
        }

        .icon_box {
            display: flex;
            align-items: center;
            gap: 2px;
            width: 24px;
            height: 100%;
        }

        .icon {
            display: none;
            transition: 0.2s;
        }

        &:hover {
            .icon {
                display: block;
            }
        }
    }
}

.filterForm {
    display: flex;
    align-items: center;
    height: 40px;
    padding: 0 10px;
}

:deep(.el-tooltip__trigger:focus) {
    outline: none;
}
</style>
